package com.suncaper.han_yi_system.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;

import java.util.Date;
import java.util.Map;
import java.util.UUID;

/**
 * JWT工具类
 */
public class JwtUtil {

    //有效期（一天）
    public static final Long JWT_TTL = 24 * 60 * 60 * 1000L;
    //设置秘钥
    public static final String JWT_KEY = "2a10UGXPmJURYRZ9JHjIO0kezIkJ4IVa7I7MkkJ2kByig7uw40w8Wo62a10UGXPmJURYRZ9JHjIO0kezIkJ4IVa7I7MkkJ2kByig7uw40w8Wo6";

    //jwt 用户信息-key
    public static final String USER_INFO_KEY = "user_info_key";
    //jwt 用户信息-id
    public static final String USER_INFO_ID = "user_info_id";
    //jwt 用户信息-username
    public static final String USER_INFO_USERNAME = "user_info_username";

    public static String getUUID(){
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 生成jtw
     * @param claims token中要存放的数据（json格式）
     * @return 生成后的token字符串
     */
    public static String createJWT(Map<String,Object> claims) {
        JwtBuilder builder = getJwtBuilder(claims, null, getUUID());// 设置过期时间
        return builder.compact();
    }

    /**
     * 生成jtw
     * @param claims token中要存放的数据（json格式）
     * @param ttlMillis token超时时间
     * @return 生成后的token字符串
     */
    public static String createJWT(Map<String,Object> claims, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(claims, ttlMillis, getUUID());// 设置过期时间
        return builder.compact();
    }

    /**
     * 创建token
     * @param id 唯一标识
     * @param claims token中要存放的数据（json格式）
     * @param ttlMillis token超时时间
     * @return 生成后的token字符串
     */
    public static String createJWT(Map<String,Object> claims, Long ttlMillis, String id) {
        JwtBuilder builder = getJwtBuilder(claims, ttlMillis, id);// 设置过期时间
        return builder.compact();
    }


    /**
     * 获取JwtBuilder对象
     *
     * @param claims token中要存放的数据（json格式）
     * @param ttlMillis Token的存活时间（毫秒）
     * @param uuid 唯一的ID
     * @return JwtBuilder对象
     */
    private static JwtBuilder getJwtBuilder(Map<String,Object> claims, Long ttlMillis, String uuid) {
        // 获取当前时间戳
        long nowMillis = System.currentTimeMillis();
        // 将时间戳转换为Date对象
        Date now = new Date(nowMillis);
        // 如果ttlMillis为空，则使用JwtUtil中的默认TTL
        if(ttlMillis==null){
            ttlMillis=JwtUtil.JWT_TTL;
        }
        // 计算过期时间戳
        long expMillis = nowMillis + ttlMillis;
        // 将过期时间戳转换为Date对象
        Date expDate = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid)              // 唯一的ID
                .setSubject("authentication")    // 主题  可以是JSON数据
                .setIssuer("dashuaibi")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .addClaims(claims)         // 自定义数据
                .signWith(Keys.hmacShaKeyFor(
                        Decoders.BASE64URL.decode(JWT_KEY))) // 加密算法以及密匙(根据密钥长度自动选择加密算法)
                .setExpiration(expDate); // 设置过期时间
    }

    /**
     * 解析token
     *
     * @param token 加密后的token字符串
     * @return Claims对象，包含token中的数据（json格式）
     */
    public static Claims parseToken(String token) throws Exception {
        Claims claims = null;
        try {
            claims =  Jwts.parserBuilder() // 得到DefaultJwtParser
                    .setSigningKey(Decoders.BASE64.decode(JWT_KEY)) // 设置秘钥
                    .build() // 得到JwtParser对象
                    .parseClaimsJws(token) // 解析token字符串得到Claims对象
                    .getBody(); // 获取Claims对象中的数据，类似于Map结构
        } catch (Exception e) {
            throw new RuntimeException("token解析失败");
        }
        return claims;
    }


}